In numerical analysis, the Horner scheme (also known as Horner algorithm), named after William George Horner, is an algorithm for the efficient evaluation of polynomials in monomial form. Horner's method describes a manual process by which one may approximate the roots of a polynomial equation. The Horner scheme can also be viewed as a fast algorithm for dividing a polynomial by a linear polynomial with Ruffini's rule.
Contents |
Given the polynomial
where are real numbers, we wish to evaluate the polynomial at a specific value of x, say x0.
To accomplish this, we define a new sequence of constants as follows:
Then b0 is the value of p(x0).
To see why this works, note that the polynomial can be written in the form
Thus, by iteratively substituting the into the expression,
Evaluate
We use synthetic division as follows:
x₀│ x³ x² x¹ x⁰ 3 │ 2 -6 2 -1 │ 6 0 6 └──────────────────────── 2 0 2 5
The entries in the third row are the sum of those in the first two. Each entry in the second row is the product of the x-value (3 in this example) with the third-row entry immediately to the left. The entries in the first row are the coefficients of the polynomial to be evaluated. Then the remainder of on division by is 5.
But by the remainder theorem, we know that the remainder is . Thus
In this example, if we can see that , the entries in the third row. So, synthetic division is based on Horner Scheme.
As a consequence of the polynomial remainder theorem, the entries in the third row are the coefficients of the second-degree polynomial, the quotient of on division by . The remainder is 5. This makes Horner's method useful for polynomial long division.
Divide by :
2 │ 1 -6 11 -6 │ 2 -8 6 └──────────────────────── 1 -4 3 0
The quotient is .
Let and . Divide by using Horner's scheme.
2 │ 4 -6 0 3 │ -5 ────┼──────────────────────┼─────── 1 │ 2 -2 -1 │ 1 │ │ └──────────────────────┼─────── 2 -2 -1 1 │ -4
The third row is the sum of the first two rows, divided by 2. Each entry in the second row is the product of 1 with the third-row entry to the left. The answer is
Horner's method is a fast, code-efficient method for multiplication and division of binary numbers on a microcontroller with no hardware multiplier. One of the binary numbers to be multiplied is represented as a trivial polynomial, where, (using the above notation): ai = 1, and x = 2. Then, x (or x to some power) is repeatedly factored out. In this binary numeral system (base 2), x = 2, so powers of 2 are repeatedly factored out.
For example, to find the product of two numbers, (0.15625) and m:
To find the product of two binary numbers, "d" and "m".
In general, for a binary number with bit values: () the product is:
At this stage in the algorithm, it is required that terms with zero-valued coefficients are dropped, so that only binary coefficients equal to one are counted, thus the problem of multiplication or division by zero is not an issue, despite this implication in the factored equation:
The denominators all equal one (or the term is absent), so this reduces to:
or equivalently (as consistent with the "method" described above):
In binary (base 2) math, multiplication by a power of 2 is merely a register shift operation. Thus, multiplying by 2 is calculated in base-2 by an arithmetic shift. The factor (2−1) is a right arithmetic shift, a (0) results in no operation (since 20 = 1, is the multiplicative identity element), and a (21) results in a left arithmetic shift. The multiplication product can now be quickly calculated using only arithmetic shift operations, addition and subtraction.
The method is particularly fast on processors supporting a single-instruction shift-and-addition-accumulate. Compared to a C floating-point library, Horner's method sacrifices some accuracy, however it is nominally 13 times faster (16 times faster when the "canonical signed digit" (CSD) form is used), and uses only 20% of the code space.[1]
Using the Horner scheme in combination with Newton's zero finding method it is possible to approximate the real roots of a polynomial. The algorithm is as follows. Given a polynomial of degree with zeros make some initial guess such that . Now follow the steps outline below.
1. Using Newton's method find the largest zero, of using the guess .
2. Use the Horner scheme to divide out to obtain . Return to step 1 but use the polynomial and the initial guess .
These two steps are repeated until all real zeros are found for the polynomial. If the approximated zeros are not precise enough, the obtained values can be used as initial guesses for Newton's method but using the full polynomial rather than the reduced polynomials.[2]
Consider the polynomial,
which can be expanded to,
From the above we know that the largest root of this polynomial is 7 so we are able to make an initial guess of 8. Using Newton's method the first zero of 7 is found as shown in black in the figure to the right. Next is divided by to obtain,
which is drawn in red in the figure to the right. Newton's method is used to find the largest zero of this polynomial with an initial guess of 7. The largest zero of this polynomial which corresponds to the second largest zero of the original polynomial is found at 3 and is circled in red. The degree 5 polynomial is now divided by to obtain,
which is shown in yellow. The zero for this polynomial is found at 2 again using Newton's method and is circled in yellow. The Horner scheme is now used to obtain,
which is shown in green and found to have a zero at -3. This polynomial is further reduced to,
which is shown in blue and yields a zero of -5. The final root of the original polynomial may be found by either using the final zero as an initial guess for Newton's method, or by reducing and solving the linear equation. As can be seen, the expected roots of -8, -5, -3, 2, 3, and 7 were found.
The following Octave code was used in the example above to implement the Horner scheme.
function [y b] = horner(a,x) % Input a is the polynomial coefficient vector, x the value to be evaluated at. % The output y is the evaluated polynomial and b the divided coefficient vector. b(1) = a(1); for i = 2:length(a) b(i) = a(i)+x*b(i-1); end y = b(length(a)); b = b(1:length(b)-1); end
The following Python code implements the Horner scheme.
def horner(x, *args): """A function that implements the Horner Scheme for evaluating a polynomial of coefficients *args in x.""" result = 0 for coefficient in args: result = result * x + coefficient return result
The Horner scheme is often used to convert between different positional numeral systems – in which case x is the base of the number system, and the ai coefficients are the digits of the base-x representation of a given number – and can also be used if x is a matrix, in which case the gain in computational efficiency is even greater. In fact, when x is a matrix, further acceleration is possible which exploits the structure of matrix multiplication, and only instead of n multiplies are needed (at the expense of requiring more storage) using the 1973 method of Paterson and Stockmeyer[3].
Evaluation using the monomial form of a degree-n polynomial requires at most n additions and (n2 + n)/2 multiplications, if powers are calculated by repeated multiplication and each monomial is evaluated individually. (This can be reduced to n additions and 2n - 1 multiplications by evaluating the powers of x iteratively.) If numerical data are represented in terms of digits (or bits), then the naive algorithm also entails storing approximately 2n times the number of bits of x (the evaluated polynomial has approximate magnitude xn, and one must also store xn itself). By contrast, Horner's scheme requires only n additions and n multiplications, and its storage requirements are only n times the number of bits of x. Alternatively, Horner's scheme can be computed with n fused multiply–adds. Horner's scheme can also be extended to evaluate the first k derivatives of the polynomial with kn additions and multiplications.[4]
It has been shown that the Horner scheme is optimal, in the sense that any algorithm to evaluate an arbitrary polynomial must use at least as many operations. That the number of additions required is minimal was shown by Alexander Ostrowski in 1954; that the number of multiplications is minimal by Victor Pan, in 1966. When x is a matrix, the Horner scheme is not optimal.
This assumes that the polynomial is evaluated in monomial form and no preconditioning of the representation is allowed, which makes sense if the polynomial is evaluated only once. However, if preconditioning is allowed and the polynomial is to be evaluated many times, then faster algorithms are possible. They involve a transformation of the representation of the polynomial. In general, a degree-n polynomial can be evaluated using only multiplications and n additions (see Knuth: The Art of Computer Programming, Vol.2).
Even though the algorithm is named after William George Horner, who described it in 1819, the method was already known to Isaac Newton in 1669, the Chinese mathematician Qin Jiushao in his Mathematical Treatise in Nine Sections in the 13th century, and even earlier to the 11th century Song dynasty mathematician Jia Xian, and the Persian Muslim mathematician Sharaf al-Dīn al-Tūsī in the 12th century.[6] The earliest use of Horner's scheme was in The Nine Chapters on the Mathematical Art, a Chinese work of the Han Dynasty (202 BC – 220 AD) edited by Liu Hui (fl. 3rd century).[7]